package com.vercon.otamirror;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;


import androidx.annotation.RequiresApi;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
//import androidx.multidex.MultiDex;

import com.abupdate.fotainject.FotaInject;
import com.abupdate.fotainject.FotaInjector;
import com.abupdate.iot_libs.OtaAgentPolicy;
import com.abupdate.iot_libs.data.constant.BroadcastConsts;
import com.abupdate.iot_libs.data.constant.SDKConfig;
import com.abupdate.iot_libs.data.local.OtaEntity;
import com.abupdate.iot_libs.data.remote.VersionInfo;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatusMgr;
import com.abupdate.iot_libs.engine.policy.PolicyConfig;
import com.abupdate.iot_libs.engine.policy.PolicyManager;
import com.abupdate.iot_libs.engine.security.FotaException;
import com.abupdate.iot_libs.engine.thread.Dispatcher;
import com.abupdate.iot_libs.engine.thread.NamedRunnable;
import com.abupdate.iot_libs.interact.base.FotaApplication;
import com.abupdate.sdk_annotation.Inject;
import com.arialyy.aria.core.Aria;
import com.facebook.cache.disk.DiskCacheConfig;
import com.facebook.common.logging.FLog;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.igexin.sdk.PushManager;
import com.tencent.bugly.crashreport.CrashReport;
import com.vercon.commonmirror.BuildConfig;
import com.vercon.commonmirror.Constants;
import com.vercon.commonmirror.ToastManager;
import com.vercon.commonmirror.base.BaseEvent;
import com.vercon.commonmirror.cache.MirrorDataStorage;
import com.vercon.commonmirror.component.MirrorToastComponent;
import com.vercon.commonmirror.network.MainApi;
import com.vercon.commonmirror.utils.APPUtil;
import com.vercon.commonmirror.utils.LogUtils;
import com.vercon.commonmirror.utils.ThreadUtil;
import com.vercon.commonmirror.utils.TypefaceUtil;

import com.vercon.otamirror.mode.FirmwareMode;
import com.vercon.otamirror.receiver.OtaReceiver;
import com.vercon.otamirror.service.FloatService;
import com.vercon.otamirror.utils.helper.AppUtil;
import com.vercon.otamirror.utils.helper.Installation;
import com.vercon.otamirror.utils.helper.RxTime;


import org.greenrobot.eventbus.EventBus;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.functions.Consumer;
import io.reactivex.plugins.RxJavaPlugins;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.autosize.AutoSizeConfig;
import me.jessyan.autosize.unit.Subunits;
import skin.support.SkinCompatManager;
import skin.support.app.SkinAppCompatViewInflater;
import skin.support.app.SkinCardViewInflater;
import skin.support.constraint.app.SkinConstraintViewInflater;
import skin.support.design.app.SkinMaterialViewInflater;
import skin.support.utils.SkinPreference;


/**
 * Created by csh on 2020/7/27
 */
public class MainApplication extends FotaApplication  {

    private static MainApplication application;

    public boolean isForeground = true;
    public static Context sCx;
    public static boolean isCompleted = false;
    public boolean isKiller = true;//是否是k系列板卡
    public boolean isLightKiller = true;//是否是k系列板卡,固件控制方式灯光


    @SuppressLint("CheckResult")
    @Override
    public void onCreate() {
        super.onCreate();
        //一个进程初始化一次，这里有两个进程，所以做个限制
        if (getCurProcessName(this).equals(getPackageName())) {
            //MultiDex.install(this);
            application = this;
            initializeFresco();
            //对单位的自定义配置, 请在 App 启动时完成
            AutoSizeConfig.getInstance().getUnitsManager().setSupportSubunits(Subunits.MM);

            //换肤
            SkinCompatManager.withoutActivity(this)
                    .addInflater(new SkinAppCompatViewInflater())           // 基础控件换肤初始化
                    .addInflater(new SkinMaterialViewInflater())            // material design 控件换肤初始化[可选]
                    .addInflater(new SkinConstraintViewInflater())          // ConstraintLayout 控件换肤初始化[可选]
                    .addInflater(new SkinCardViewInflater())                // CardView v7 控件换肤初始化[可选]
                    .setSkinStatusBarColorEnable(false)                     // 关闭状态栏换肤，默认打开[可选]
                    .setSkinWindowBackgroundEnable(false)                   // 关闭windowBackground换肤，默认打开[可选]
                    .loadSkin();
            SkinPreference.init(this);


            //土司
            ToastManager.instance().setToastComponent(new MirrorToastComponent(this.getApplicationContext()));
            ToastManager.instance().initialize(this);



            //缓存
            MirrorDataStorage.instance().initialize(MainApplication.this, MainApplication.this.getPackageName());
            //

            Observable.timer(0, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io()).subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            MainApi.getInstance().setApplication(MainApplication.this);
                            //初始化bugly
                            initBugly();
                            //字体样式设置，全局中文使用SourceHanSansCN-Light.otf，但好像有问题，目前使用Alibaba-PuHuiTi-Light.ttf
                            //全局数字、英文使用DIN_Light.otf
                            //时钟使用Genome-Thin.otf
                            TypefaceUtil.replaceSystemDefaultFontRes(MainApplication.this, "alibaba_puhuiti_regular");



                            //多任务下载初始化
                            Aria.init(MainApplication.this);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {

                        }
                    });



            int size = 1920;//1920*1080  S
            isKiller = isAndroid_11();
            isLightKiller = isLightKiller();
            if (isKiller){
                size = 1280;//1280*800 k
            }
            AutoSizeConfig.getInstance()
                    .setBaseOnWidth(true)
                    .setDesignWidthInDp(size)
                    .setCustomFragment(true)
                    .setLog(true);

            Intent serviceIntent = new Intent(this, FloatService.class);
            startService(serviceIntent);


        }
        RxJavaPlugins.setErrorHandler(Throwable::printStackTrace);

    }

    @Override
    protected void init() {
        LogUtils.e("FotaApplication", "init() " );
        sCx = this;
        Installation.init();
        SDKConfig.setIsTest(false);
        Dispatcher.getDispatcher().enqueue(new NamedRunnable("FotaApplication") {
            @Override
            protected void execute() {
                String mid = AppUtil.getSN();
                try {
                    OtaAgentPolicy.Builder builder = OtaAgentPolicy.init(sCx)
                            .isReportLog(true)
                            .setClientDefaultTriggerCycle(3600000)//90000000默认是这个数，等于25小时    90000000，一个小时
                            .setMid(mid);
                    builder.commit();

                    isCompleted = true;
                    LogUtils.e("FotaApplication", "init()成功 " );
                    initfirmwareData();
                } catch (FotaException e) {
                    e.printStackTrace();
                    LogUtils.e(e.getMessage());

                }
            }
        });


    }


    @Override
    protected void registerFOTANotify() {
        OtaReceiver otaReceiver = new OtaReceiver();

        registerReceiver(otaReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        //升级结果广播
        LocalBroadcastManager.getInstance(this).registerReceiver(otaReceiver, new IntentFilter(BroadcastConsts.ACTION_FOTA_UPDATE_RESULT));
        //升级推送广播
        LocalBroadcastManager.getInstance(this).registerReceiver(otaReceiver, new IntentFilter(BroadcastConsts.ACTION_FOTA_NOTIFY));
        //收到新版本通知
        OtaAgentPolicy.setNewVersionListener(MainApplication::onReceiverNewVersion);
    }

    public static void onReceiverNewVersion(List<VersionInfo> list) {
        LogUtils.e("FotaApplication", "onReceiverNewVersion() new version:" + list.get(0).versionAlias);
        VersionInfo  versionInfo =  list.get(0);
//        LogUtils.d("FotaApplication", "FOTA App is displayed in the foreground, will ignore this notify");
        LogUtils.e("FotaApplication versionInfo=", versionInfo.toString());

        if (policyManager != null) {
            FirmwareMode mode = new FirmwareMode(APPUtil.getFirmwareUpdateVersion_k(versionInfo.versionName),
                    APPUtil.getFirmwareUpdateVersion_k(versionInfo.oldVersionName), versionInfo.deltaUrl,
                    AppUtil.getContent(versionInfo.content), policyManager.isDownloadForce(), versionInfo.publishDate, true);
            LogUtils.e("FotaApplication", "33");

            EventBus.getDefault().post(mode);
        }else {
            LogUtils.e("FotaApplication", "policyManager 为空");
        }


    }

    private String getCurProcessName(Context context) {
        int pid = android.os.Process.myPid();
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo appProcess : activityManager.getRunningAppProcesses()) {
            if (appProcess.pid == pid) {
                return appProcess.processName;
            }
        }
        return "";
    }

    /**
     * 重启应用
     */
    private void restartApp() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        android.os.Process.killProcess(android.os.Process.myPid()); //结束进程之前可以把你程序的注销或者退出代码放在这段代码之前
    }




    private void initBugly() {
        Context context = getApplicationContext();
        // 获取当前包名
        String packageName = context.getPackageName();
        // 获取当前进程名
        String processName = getProcessName(android.os.Process.myPid());
        // 设置是否为上报进程
        CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context);
        strategy.setUploadProcess(processName == null || processName.equals(packageName));
        // 初始化Bugly b isDebug,true为正式版启用，false为测试版启用
        CrashReport.initCrashReport(context, "4d70fdc098", BuildConfig.DEBUG, strategy);
    }



    public static MainApplication getContext() {
        return application;
    }


    private void initGeTui() {
        LogUtils.d("MainApplication", "initializing GeTui sdk...");

        PushManager.getInstance().initialize(this);
        if (BuildConfig.DEBUG) {
            //切勿在 release 版本上开启调试日志
            PushManager.getInstance().setDebugLogger(this, s -> LogUtils.i("PUSH_LOG", s));
        }
    }


    private void initializeFresco(){
        File cacheFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"FrescoCache");
        if(!cacheFile.exists()){
            cacheFile.mkdirs();
        }
        Fresco.initialize(this, ImagePipelineConfig.newBuilder(this)
                .setMainDiskCacheConfig(
                        DiskCacheConfig.newBuilder(this)
                                //磁盘缓存路径
                                .setBaseDirectoryPath(cacheFile)
                                .setMaxCacheSize(500*1024*1024)
                                .build()
                )
               .setDownsampleEnabled(true)
                .build());
        if(BuildConfig.DEBUG){
            FLog.setMinimumLoggingLevel(FLog.VERBOSE);
        }
    }


    /**
     * 获取进程号对应的进程名
     *
     * @param pid 进程号
     * @return 进程名
     */
    private static String getProcessName(int pid) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline"));
            String processName = reader.readLine();
            if (!TextUtils.isEmpty(processName)) {
                processName = processName.trim();
            }
            return processName;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException exception) {
                exception.printStackTrace();
            }
        }
        return null;
    }





    private static final String SYSTEM_NAVIGATION = "system_navigation";
    public static final String HIDE_NAVIGATION = "hide_navigation";
    public static final String ACTION_NAVIGATION_SHOW = "android.intent.action.NAVIGATION_SHOW";
    public static final String ACTION_NAVIGATION_HIDE = "android.intent.action.NAVIGATION_HIDE";

    /**
     * 设置虚拟键显示隐藏
     *
     * @param isChecked
     */
    public void setVirtualKey(boolean isChecked) {
        ThreadUtil.getInstance().getExecutorService().execute(() -> {
            try {
//                if (isChecked) {
//                    Thread.sleep(1000);
//                }
                LogUtils.d("setVirtualKey 显示虚拟键: " + isChecked);
                if (Integer.parseInt(Build.VERSION.RELEASE) > 10) {
                    //A99的11系统使用这个
                    Settings.System.putInt(getContentResolver(), SYSTEM_NAVIGATION, isChecked ? 1 : 0);
                } else {
                    //A99的10系统使用这个
                    sendBroadcast(isChecked ? new Intent(ACTION_NAVIGATION_SHOW) : new Intent(ACTION_NAVIGATION_HIDE));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!isKiller) {
                Intent intent = new Intent("com.xbh.action.HIDE_STATUS_BAR");
                intent.putExtra("hide", !isChecked);//true则隐藏，false则显示
                sendBroadcast(intent);
            }
        });
    }

    /**
     * 重启设备
     */
    public static void reboot() {
        Intent intent = new Intent(Intent.ACTION_REBOOT);
        intent.putExtra("nowait", 1);
        intent.putExtra("interval", 1);
        intent.putExtra("window", 0);
        OtaAgentPolicy.sCx.sendBroadcast(intent);
    }

    @Inject
    public OtaEntity mOtaEntity;
    private FotaInject fotaInject;
    @Inject
    public static PolicyManager policyManager;
    private OtaStatusMgr otaStatusMgr;
    @Inject
    public VersionInfo versionInfo;
    public  void initfirmwareData() {
        RxTime.newInstance()
                .setPeriod(500)
                .setMinTime(1000)
                .setTimeout(15 * 1000)
                .setICondition(() -> MainApplication.isCompleted)
                .enqueue(true, new RxTime.IEnqueueListener() {
                    @Override
                    public void onComplete() {
                        try {
                            //获取相关数据
                            fotaInject = FotaInjector.inject(MainApplication.sCx);
                            otaStatusMgr = OtaStatusMgr.getInstance();
                            PolicyConfig policyConfig = mOtaEntity.getPolicyManager().getPolicyConfig();
                            //关闭电量检测
                            policyConfig.request_battery(false);

                            LogUtils.e("versionInfo=" + versionInfo.toString());
                        }catch (Exception e){
                            LogUtils.e("Exception=" + e.getMessage());
                        }

                        // getVersion();
                    }

                    @Override
                    public void onTimeOut() {
                        LogUtils.e("初始化失败，请稍后重试");
                        //Toast.makeText(getActivity(), "初始化失败，请稍后重试", Toast.LENGTH_SHORT).show();
                    }
                });
    }


    private boolean isAndroid_11(){

        DisplayMetrics metric = new DisplayMetrics();
        WindowManager mWindowManager  = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        mWindowManager.getDefaultDisplay().getMetrics(metric);

        int width=metric.widthPixels; // 宽度（PX）
        int height=metric.heightPixels; // 高度（PX）

        float density=metric.density; // 密度（0.75 / 1.0 / 1.5）
        int densityDpi=metric.densityDpi; // 密度DPI（120 / 160 / 240）

        //屏幕宽度算法:屏幕宽度（像素）/屏幕密度
        int screenWidth = (int) (width/density);//屏幕宽度(dp)
        int screenHeight = (int)(height/density);//屏幕高度(dp)

        String a = "宽度:" + width + " 高度:" + height + " 密度:" + density + " 密度DPI:" + densityDpi
                + "\r\n屏幕dp宽度：" + screenWidth + " 屏幕dp高度：" + screenHeight;
        LogUtils.e(a);
        if (screenWidth > 1150 && screenWidth < 1300){//这个最小宽度代表是K系列的
            return true;
        }else if (screenWidth == 1920){//这个宽度代表是S系列
            return false;
        }
        return false;
    }
    //宽度:1920 高度:984 密度:2.0 密度DPI:320   3568的
    //宽度:1280 高度:752 密度:1.0 密度DPI:160  199

    private boolean isLightKiller(){

        String str = Build.DISPLAY;
        LogUtils.e("str="+str);
        if (str .contains("3568") || str .contains("A99")){//这个k系列的
            LogUtils.e("这个K系列的");
            return true;
        }else {
            LogUtils.e("这个S系列的");
            return false;
        }
    }



}
   